home *** CD-ROM | disk | FTP | other *** search
- *
- * asm_support.asm - AmigaOS utility functions in assembly language
- *
- * Basilisk II (C) 1997-2001 Christian Bauer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/macros.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/tasks.i"
- INCLUDE "dos/dos.i"
- INCLUDE "devices/timer.i"
-
- XDEF _AtomicAnd
- XDEF _AtomicOr
- XDEF _MoveVBR
- XDEF _DisableSuperBypass
- XDEF _Execute68k
- XDEF _Execute68kTrap
- XDEF _TrapHandlerAsm
- XDEF _ExceptionHandlerAsm
- XDEF _Scod060Patch1
- XDEF _Scod060Patch2
- XDEF _ThInitFPUPatch
- XDEF _AsmTriggerNMI
-
- XREF _OldTrapHandler
- XREF _OldExceptionHandler
- XREF _IllInstrHandler
- XREF _PrivViolHandler
- XREF _EmulatedSR
- XREF _IRQSigMask
- XREF _InterruptFlags
- XREF _MainTask
- XREF _SysBase
- XREF _quit_emulator
-
- SECTION text,CODE
-
- MACHINE 68020
-
- *
- * Atomic bit operations (don't trust the compiler)
- *
-
- _AtomicAnd move.l 4(sp),a0
- move.l 8(sp),d0
- and.l d0,(a0)
- rts
-
- _AtomicOr move.l 4(sp),a0
- move.l 8(sp),d0
- or.l d0,(a0)
- rts
-
- *
- * Move VBR away from 0 if neccessary
- *
-
- _MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp)
- move.l _SysBase,a6
-
- lea getvbr,a5 ;VBR at 0?
- JSRLIB Supervisor
- tst.l d0
- bne.s 1$
-
- move.l #$400,d0 ;Yes, allocate memory for new table
- move.l #MEMF_PUBLIC,d1
- JSRLIB AllocMem
- tst.l d0
- beq.s 1$
-
- JSRLIB Disable
-
- move.l d0,a5 ;Copy old table
- move.l d0,a1
- sub.l a0,a0
- move.l #$400,d0
- JSRLIB CopyMem
- JSRLIB CacheClearU
-
- move.l a5,d0 ;Set VBR
- lea setvbr,a5
- JSRLIB Supervisor
-
- JSRLIB Enable
-
- 1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6
- rts
-
- getvbr movec vbr,d0
- rte
-
- setvbr movec d0,vbr
- rte
-
- *
- * Disable 68060 Super Bypass mode
- *
-
- _DisableSuperBypass
- movem.l d0-d1/a0-a1/a5-a6,-(sp)
- move.l _SysBase,a6
-
- lea dissb,a5
- JSRLIB Supervisor
-
- movem.l (sp)+,d0-d1/a0-a1/a5-a6
- rts
-
- MACHINE 68060
-
- dissb movec pcr,d0
- bset #5,d0
- movec d0,pcr
- rte
-
- MACHINE 68020
-
- *
- * Execute 68k subroutine (must be ended with rts)
- * r->a[7] and r->sr are unused!
- *
-
- ; void Execute68k(uint32 addr, M68kRegisters *r);
- _Execute68k
- move.l 4(sp),d0 ;Get arguments
- move.l 8(sp),a0
-
- movem.l d2-d7/a2-a6,-(sp) ;Save registers
-
- move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
- pea 1$ ;Push return address on stack
- move.l d0,-(sp) ;Push pointer to 68k routine on stack
- movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
-
- rts ;Jump into 68k routine
-
- 1$ move.l a6,-(sp) ;Save a6
- move.l 4(sp),a6 ;Get pointer to M68kRegisters
- movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
- move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
- addq.l #4,sp ;Remove pointer from stack
-
- movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
- rts
-
- *
- * Execute MacOS 68k trap
- * r->a[7] and r->sr are unused!
- *
-
- ; void Execute68kTrap(uint16 trap, M68kRegisters *r);
- _Execute68kTrap
- move.l 4(sp),d0 ;Get arguments
- move.l 8(sp),a0
-
- movem.l d2-d7/a2-a6,-(sp) ;Save registers
-
- move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
- move.w d0,-(sp) ;Push trap word on stack
- subq.l #8,sp ;Create fake A-Line exception frame
- movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
-
- move.l a2,-(sp) ;Save a2 and d2
- move.l d2,-(sp)
- lea 1$,a2 ;a2 points to return address
- move.w 16(sp),d2 ;Load trap word into d2
-
- jmp ([$28.w],10) ;Jump into MacOS A-Line handler
-
- 1$ move.l a6,-(sp) ;Save a6
- move.l 6(sp),a6 ;Get pointer to M68kRegisters
- movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
- move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
- addq.l #6,sp ;Remove pointer and trap word from stack
-
- movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
- rts
-
- *
- * Exception handler of main task (for 60Hz interrupts)
- *
-
- _ExceptionHandlerAsm
- move.l d0,-(sp) ;Save d0
-
- and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C?
- bne.s 2$
-
- move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR?
- and.w #$0700,d0
- bne 1$
- move.w #$0064,-(sp) ;Yes, fake interrupt stack frame
- pea 1$
- move.w _EmulatedSR,d0
- move.w d0,-(sp)
- or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode
- move.w d0,_EmulatedSR
- move.l $64.w,-(sp) ;Jump to MacOS interrupt handler
- rts
-
- 1$ move.l (sp)+,d0 ;Restore d0
- rts
-
- 2$ JSRLIB Forbid ;Waiting for Dos signal?
- sub.l a1,a1
- JSRLIB FindTask
- move.l d0,a0
- move.l TC_SIGWAIT(a0),d0
- move.l TC_SIGRECVD(a0),d1
- JSRLIB Permit
- btst #SIGB_DOS,d0
- beq 3$
- btst #SIGB_DOS,d1
- bne 4$
-
- 3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets
- JSRLIB GetMsg
-
- move.w _EmulatedSR,d0
- or.w #$0700,d0 ;Disable all interrupts
- move.w d0,_EmulatedSR
- moveq #0,d0 ;Disable all exception signals
- moveq #-1,d1
- JSRLIB SetExcept
- jsr _quit_emulator ;CTRL-C, quit emulator
- 4$ move.l (sp)+,d0
- rts
-
- *
- * Process Manager 68060 FPU patches
- *
-
- _Scod060Patch1 fsave -(sp) ;Save FPU state
- tst.b 2(sp) ;Null?
- beq.s 1$
- fmovem.x fp0-fp7,-(sp) ;No, save FPU registers
- fmove.l fpiar,-(sp)
- fmove.l fpsr,-(sp)
- fmove.l fpcr,-(sp)
- pea -1 ;Push "FPU state saved" flag
- 1$ move.l d1,-(sp)
- move.l d0,-(sp)
- bsr.s 3$ ;Switch integer registers and stack
- addq.l #8,sp
- tst.b 2(sp) ;New FPU state null or "FPU state saved" flag set?
- beq.s 2$
- addq.l #4,sp ;Flag set, skip it
- fmove.l (sp)+,fpcr ;Restore FPU registers and state
- fmove.l (sp)+,fpsr
- fmove.l (sp)+,fpiar
- fmovem.x (sp)+,fp0-fp7
- 2$ frestore (sp)+
- movem.l (sp)+,d0-d1
- rts
-
- 3$ move.l 4(sp),a0 ;Switch integer registers and stack
- move sr,-(sp)
- movem.l d2-d7/a2-a6,-(sp)
- cmp.w #0,a0
- beq.s 4$
- move.l sp,(a0)
- 4$ move.l $36(sp),a0
- movem.l (a0)+,d2-d7/a2-a6
- move (a0)+,sr
- move.l a0,sp
- rts
-
- _Scod060Patch2 move.l d0,-(sp) ;Create 68060 null frame on stack
- move.l d0,-(sp)
- move.l d0,-(sp)
- frestore (sp)+ ;and load it
- rts
-
- *
- * Thread Manager 68060 FPU patches
- *
-
- _ThInitFPUPatch tst.b $40(a4)
- bne.s 1$
- moveq #0,d0 ;Create 68060 null frame on stack
- move.l d0,-(a3)
- move.l d0,-(a3)
- move.l d0,-(a3)
- 1$ rts
-
- *
- * Trap handler of main task
- *
-
- _TrapHandlerAsm:
- cmp.l #4,(sp) ;Illegal instruction?
- beq.s doillinstr
- cmp.l #10,(sp) ;A-Line exception?
- beq.s doaline
- cmp.l #8,(sp) ;Privilege violation?
- beq.s doprivviol
- cmp.l #9,(sp) ;Trace?
- beq dotrace
- cmp.l #3,(sp) ;Illegal Address?
- beq.s doilladdr
-
- cmp.l #32,(sp)
- blt 1$
- cmp.l #47,(sp)
- ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors
-
- 1$ move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler
- rts
-
- *
- * TRAP #0 - 15 Instruction Vectors
- *
-
- doTrapXX move.l a0,(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.l 2*4(sp),-(a0) ;Copy 4-word stack frame to user stack
- move.l 1*4(sp),-(a0)
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
-
- addq.l #4*2,sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l $2d*4.w,-(sp) ;Jump to MacOS exception handler
- rts
-
-
- *
- * trace Vector
- *
-
- dotrace move.l a0,(sp) ;Save a0
-
- move.l usp,a0 ;Get user stack pointer
- move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack
- move.l 2*4(sp),-(a0)
- move.l 1*4(sp),-(a0)
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
-
- lea 6*2(sp),sp ;Remove exception frame from supervisor stack
- andi #$18ff,sr ;Switch to user mode, enable interrupts, disable trace
-
- move.l $24.w,-(sp) ;Jump to MacOS exception handler
- rts
-
-
- *
- * A-Line handler: call MacOS A-Line handler
- *
-
- doaline move.l a0,(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.l 8(sp),-(a0) ;Copy stack frame to user stack
- move.l 4(sp),-(a0)
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
-
- addq.l #8,sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l $28.w,-(sp) ;Jump to MacOS exception handler
- rts
-
- *
- * Illegal address handler
- *
-
- doilladdr move.l a0,(sp) ;Save a0
-
- move.l usp,a0 ;Get user stack pointer
- move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack
- move.l 2*4(sp),-(a0)
- move.l 1*4(sp),-(a0)
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
-
- lea 6*2(sp),sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l $0c.w,-(sp) ;Jump to MacOS exception handler
- rts
-
-
- *
- * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
- * to execute extended opcodes (see emul_op.h)
- *
-
- doillinstr movem.l a0/d0,-(sp)
- move.w ([6+2*4,sp]),d0
- and.w #$ff00,d0
- cmp.w #$7100,d0
- movem.l (sp)+,a0/d0
- beq 1$
-
- move.l a0,(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.l 8(sp),-(a0) ;Copy stack frame to user stack
- move.l 4(sp),-(a0)
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
-
- add.w #3*4,sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l $10.w,-(sp) ;Jump to MacOS exception handler
- rts
-
- 1$ move.l a6,(sp) ;Save a6
- move.l usp,a6 ;Get user stack pointer
-
- move.l a6,-10(a6) ;Push USP (a7)
- move.l 6(sp),-(a6) ;Push PC
- move.w 4(sp),-(a6) ;Push SR
- subq.l #4,a6 ;Skip saved USP
- move.l (sp),-(a6) ;Push old a6
- movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
- move.l a6,usp ;Update USP
-
- add.w #12,sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp
- jsr _IllInstrHandler
- addq.l #4,sp
-
- movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
- addq.l #4,sp ;Skip saved USP (!!)
- rtr ;Return from exception
-
- *
- * Privilege violation handler: MacOS runs in supervisor mode,
- * so we have to emulate certain privileged instructions
- *
-
- doprivviol move.l d0,(sp) ;Save d0
- move.w ([6,sp]),d0 ;Get instruction word
-
- cmp.w #$40e7,d0 ;move sr,-(sp)?
- beq pushsr
- cmp.w #$46df,d0 ;move (sp)+,sr?
- beq popsr
-
- cmp.w #$007c,d0 ;ori #xxxx,sr?
- beq orisr
- cmp.w #$027c,d0 ;andi #xxxx,sr?
- beq andisr
-
- cmp.w #$46fc,d0 ;move #xxxx,sr?
- beq movetosrimm
-
- cmp.w #$46ef,d0 ;move (xxxx,sp),sr?
- beq movetosrsprel
- cmp.w #$46d8,d0 ;move (a0)+,sr?
- beq movetosra0p
- cmp.w #$46d9,d0 ;move (a1)+,sr?
- beq movetosra1p
-
- cmp.w #$40f8,d0 ;move sr,xxxx.w?
- beq movefromsrabs
- cmp.w #$40d0,d0 ;move sr,(a0)?
- beq movefromsra0
- cmp.w #$40d7,d0 ;move sr,(sp)?
- beq movefromsrsp
-
- cmp.w #$f327,d0 ;fsave -(sp)?
- beq fsavepush
- cmp.w #$f35f,d0 ;frestore (sp)+?
- beq frestorepop
- cmp.w #$f32d,d0 ;fsave xxx(a5) ?
- beq fsavea5
- cmp.w #$f36d,d0 ;frestore xxx(a5) ?
- beq frestorea5
-
- cmp.w #$4e73,d0 ;rte?
- beq pvrte
-
- cmp.w #$40c0,d0 ;move sr,d0?
- beq movefromsrd0
- cmp.w #$40c1,d0 ;move sr,d1?
- beq movefromsrd1
- cmp.w #$40c2,d0 ;move sr,d2?
- beq movefromsrd2
- cmp.w #$40c3,d0 ;move sr,d3?
- beq movefromsrd3
- cmp.w #$40c4,d0 ;move sr,d4?
- beq movefromsrd4
- cmp.w #$40c5,d0 ;move sr,d5?
- beq movefromsrd5
- cmp.w #$40c6,d0 ;move sr,d6?
- beq movefromsrd6
- cmp.w #$40c7,d0 ;move sr,d7?
- beq movefromsrd7
-
- cmp.w #$46c0,d0 ;move d0,sr?
- beq movetosrd0
- cmp.w #$46c1,d0 ;move d1,sr?
- beq movetosrd1
- cmp.w #$46c2,d0 ;move d2,sr?
- beq movetosrd2
- cmp.w #$46c3,d0 ;move d3,sr?
- beq movetosrd3
- cmp.w #$46c4,d0 ;move d4,sr?
- beq movetosrd4
- cmp.w #$46c5,d0 ;move d5,sr?
- beq movetosrd5
- cmp.w #$46c6,d0 ;move d6,sr?
- beq movetosrd6
- cmp.w #$46c7,d0 ;move d7,sr?
- beq movetosrd7
-
- cmp.w #$4e7a,d0 ;movec cr,x?
- beq movecfromcr
- cmp.w #$4e7b,d0 ;movec x,cr?
- beq movectocr
-
- cmp.w #$f478,d0 ;cpusha dc?
- beq cpushadc
- cmp.w #$f4f8,d0 ;cpusha dc/ic?
- beq cpushadcic
-
- cmp.w #$4e69,d0 ;move usp,a1
- beq moveuspa1
- cmp.w #$4e68,d0 ;move usp,a0
- beq moveuspa0
-
- cmp.w #$4e61,d0 ;move a1,usp
- beq moved1usp
-
- pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp
- move.l a6,(sp) ;Save a6
- move.l usp,a6 ;Get user stack pointer
-
- move.l a6,-10(a6) ;Push USP (a7)
- move.l 6(sp),-(a6) ;Push PC
- move.w 4(sp),-(a6) ;Push SR
- subq.l #4,a6 ;Skip saved USP
- move.l (sp),-(a6) ;Push old a6
- movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
- move.l a6,usp ;Update USP
-
- add.w #12,sp ;Remove exception frame from supervisor stack
- andi #$d8ff,sr ;Switch to user mode, enable interrupts
-
- move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp
- jsr _PrivViolHandler
- addq.l #4,sp
-
- movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
- addq.l #4,sp ;Skip saved USP
- rtr ;Return from exception
-
- ; move sr,-(sp)
- pushsr move.l a0,-(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.w 8(sp),d0 ;Get CCR from exception stack frame
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- move.w d0,-(a0) ;Store SR on user stack
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
- move.l (sp)+,d0 ;Restore d0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; move (sp)+,sr
- popsr move.l a0,-(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.w (a0)+,d0 ;Get SR from user stack
- move.w d0,8(sp) ;Store into CCR on exception stack frame
- and.w #$00ff,8(sp)
- and.w #$e700,d0 ;Extract supervisor bits
- move.w d0,_EmulatedSR ;And save them
-
- and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
- bne 1$
- tst.l _InterruptFlags
- beq 1$
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l _SysBase,a6
- move.l _MainTask,a1
- move.l _IRQSigMask,d0
- JSRLIB Signal
- movem.l (sp)+,d0-d1/a0-a1/a6
- 1$
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
- move.l (sp)+,d0 ;Restore d0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; ori #xxxx,sr
- orisr move.w 4(sp),d0 ;Get CCR from stack
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- or.w ([6,sp],2),d0 ;Or with immediate value
- move.w d0,4(sp) ;Store into CCR on stack
- and.w #$00ff,4(sp)
- and.w #$e700,d0 ;Extract supervisor bits
- move.w d0,_EmulatedSR ;And save them
- move.l (sp)+,d0 ;Restore d0
- addq.l #4,2(sp) ;Skip instruction
- rte
-
- ; andi #xxxx,sr
- andisr move.w 4(sp),d0 ;Get CCR from stack
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- and.w ([6,sp],2),d0 ;And with immediate value
- storesr4 move.w d0,4(sp) ;Store into CCR on stack
- and.w #$00ff,4(sp)
- and.w #$e700,d0 ;Extract supervisor bits
- move.w d0,_EmulatedSR ;And save them
-
- and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
- bne.s 1$
- tst.l _InterruptFlags
- beq.s 1$
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l _SysBase,a6
- move.l _MainTask,a1
- move.l _IRQSigMask,d0
- JSRLIB Signal
- movem.l (sp)+,d0-d1/a0-a1/a6
- 1$ move.l (sp)+,d0 ;Restore d0
- addq.l #4,2(sp) ;Skip instruction
- rte
-
- ; move #xxxx,sr
- movetosrimm move.w ([6,sp],2),d0 ;Get immediate value
- bra.s storesr4
-
- ; move (xxxx,sp),sr
- movetosrsprel move.l a0,-(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.w ([10,sp],2),d0 ;Get offset
- move.w (a0,d0.w),d0 ;Read word
- move.l (sp)+,a0 ;Restore a0
- bra.s storesr4
-
- ; move (a0)+,sr
- movetosra0p move.w (a0)+,d0 ;Read word
- bra storesr2
-
- ; move (a1)+,sr
- movetosra1p move.w (a1)+,d0 ;Read word
- bra storesr2
-
- ; move sr,xxxx.w
- movefromsrabs move.l a0,-(sp) ;Save a0
- move.w ([10,sp],2),a0 ;Get address
- move.w 8(sp),d0 ;Get CCR
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- move.w d0,(a0) ;Store SR
- move.l (sp)+,a0 ;Restore a0
- move.l (sp)+,d0 ;Restore d0
- addq.l #4,2(sp) ;Skip instruction
- rte
-
- ; move sr,(a0)
- movefromsra0 move.w 4(sp),d0 ;Get CCR
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- move.w d0,(a0) ;Store SR
- move.l (sp)+,d0 ;Restore d0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; move sr,(sp)
- movefromsrsp move.l a0,-(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- move.w 8(sp),d0 ;Get CCR
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- move.w d0,(a0) ;Store SR
- move.l (sp)+,a0 ;Restore a0
- move.l (sp)+,d0 ;Restore d0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; fsave -(sp)
- fsavepush move.l (sp),d0 ;Restore d0
- move.l a0,(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- fsave -(a0) ;Push FP state
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; frestore (sp)+
- frestorepop move.l (sp),d0 ;Restore d0
- move.l a0,(sp) ;Save a0
- move.l usp,a0 ;Get user stack pointer
- frestore (a0)+ ;Restore FP state
- move.l a0,usp ;Update USP
- move.l (sp)+,a0 ;Restore a0
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- ; frestore xxx(a5) +jl+
- frestorea5 move.l (sp),d0 ;Restore d0
- move.l a0,(sp) ;Save a0
- move.l a5,a0 ;Get base register
- add.w ([6,sp],2),a0 ;Add offset to base register
- frestore (a0) ;Restore FP state from (a0)
- move.l (sp)+,a0 ;Restore a0
- addq.l #4,2(sp) ;Skip instruction
- rte
-
- ; fsave xxx(a5) +jl+
- fsavea5 move.l (sp),d0 ;Restore d0
- move.l a0,(sp) ;Save a0
- move.l a5,a0 ;Get base register
- add.w ([6,sp],2),a0 ;Add offset to base register
- fsave (a0) ;Push FP state to (a0)
- move.l (sp)+,a0 ;Restore a0
- addq.l #4,2(sp) ;Skip instruction
- rte
-
- ; rte
- pvrte movem.l a0/a1,-(sp) ;Save a0 and a1
- move.l usp,a0 ;Get user stack pointer
-
- move.w (a0)+,d0 ;Get SR from user stack
- move.w d0,8+4(sp) ;Store into CCR on exception stack frame
- and.w #$c0ff,8+4(sp)
- and.w #$e700,d0 ;Extract supervisor bits
- move.w d0,_EmulatedSR ;And save them
- move.l (a0)+,10+4(sp) ;Store return address in exception stack frame
-
- move.w (a0)+,d0 ;get format word
- lsr.w #7,d0 ;get stack frame Id
- lsr.w #4,d0
- and.w #$001e,d0
- move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length
- subq.w #4,d0 ; count only extra words
- lea 16+4(sp),a1 ; destination address (in supervisor stack)
- bra 1$
-
- 2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack
- 1$ dbf d0,2$
-
- move.l a0,usp ;Update USP
- movem.l (sp)+,a0/a1 ;Restore a0 and a1
- move.l (sp)+,d0 ;Restore d0
- rte
-
- ; sizes of exceptions stack frames
- StackFormatTable:
- dc.w 4 ; Four-word stack frame, format $0
- dc.w 4 ; Throwaway four-word stack frame, format $1
- dc.w 6 ; Six-word stack frame, format $2
- dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3
- dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4
- dc.w 4 ; Format $5
- dc.w 4 ; Format $6
- dc.w 30 ; MC68040 access error stack frame, Format $7
- dc.w 29 ; MC68010 bus and address error stack frame, format $8
- dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9
- dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a
- dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b
- dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c
- dc.w 4 ; Format $d
- dc.w 4 ; Format $e
- dc.w 4 ; Format $f
-
- ; move sr,dx
- movefromsrd0 addq.l #4,sp ;Skip saved d0
- moveq #0,d0
- move.w (sp),d0 ;Get CCR
- or.w _EmulatedSR,d0 ;Add emulated supervisor bits
- addq.l #2,2(sp) ;Skip instruction
- rte
-
- movefromsrd1 move.l (sp)+,d0
- moveq #0,d1
- move.w (sp),d1
- or.w _EmulatedSR,d1
- addq.l #2,2(sp)
- rte
-
- movefromsrd2 move.l (sp)+,d0
- moveq #0,d2
- move.w (sp),d2
- or.w _EmulatedSR,d2
- addq.l #2,2(sp)
- rte
-
- movefromsrd3 move.l (sp)+,d0
- moveq #0,d3
- move.w (sp),d3
- or.w _EmulatedSR,d3
- addq.l #2,2(sp)
- rte
-
- movefromsrd4 move.l (sp)+,d0
- moveq #0,d4
- move.w (sp),d4
- or.w _EmulatedSR,d4
- addq.l #2,2(sp)
- rte
-
- movefromsrd5 move.l (sp)+,d0
- moveq #0,d5
- move.w (sp),d5
- or.w _EmulatedSR,d5
- addq.l #2,2(sp)
- rte
-
- movefromsrd6 move.l (sp)+,d0
- moveq #0,d6
- move.w (sp),d6
- or.w _EmulatedSR,d6
- addq.l #2,2(sp)
- rte
-
- movefromsrd7 move.l (sp)+,d0
- moveq #0,d7
- move.w (sp),d7
- or.w _EmulatedSR,d7
- addq.l #2,2(sp)
- rte
-
- ; move dx,sr
- movetosrd0 move.l (sp),d0
- storesr2 move.w d0,4(sp)
- and.w #$00ff,4(sp)
- and.w #$e700,d0
- move.w d0,_EmulatedSR
-
- and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
- bne.s 1$
- tst.l _InterruptFlags
- beq.s 1$
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l _SysBase,a6
- move.l _MainTask,a1
- move.l _IRQSigMask,d0
- JSRLIB Signal
- movem.l (sp)+,d0-d1/a0-a1/a6
- 1$ move.l (sp)+,d0
- addq.l #2,2(sp)
- rte
-
- movetosrd1 move.l d1,d0
- bra.s storesr2
-
- movetosrd2 move.l d2,d0
- bra.s storesr2
-
- movetosrd3 move.l d3,d0
- bra.s storesr2
-
- movetosrd4 move.l d4,d0
- bra.s storesr2
-
- movetosrd5 move.l d5,d0
- bra.s storesr2
-
- movetosrd6 move.l d6,d0
- bra.s storesr2
-
- movetosrd7 move.l d7,d0
- bra.s storesr2
-
- ; movec cr,x
- movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word
-
- cmp.w #$8801,d0 ;movec vbr,a0?
- beq.s movecvbra0
- cmp.w #$9801,d0 ;movec vbr,a1?
- beq.s movecvbra1
- cmp.w #$1801,d0 ;movec vbr,d1?
- beq movecvbrd1
- cmp.w #$0002,d0 ;movec cacr,d0?
- beq.s moveccacrd0
- cmp.w #$1002,d0 ;movec cacr,d1?
- beq.s moveccacrd1
- cmp.w #$0003,d0 ;movec tc,d0?
- beq.s movectcd0
- cmp.w #$1003,d0 ;movec tc,d1?
- beq.s movectcd1
- cmp.w #$1000,d0 ;movec sfc,d1?
- beq movecsfcd1
- cmp.w #$1001,d0 ;movec dfc,d1?
- beq movecdfcd1
- cmp.w #$0806,d0 ;movec urp,d0?
- beq movecurpd0
- cmp.w #$0807,d0 ;movec srp,d0?
- beq.s movecsrpd0
- cmp.w #$0004,d0 ;movec itt0,d0
- beq.s movecitt0d0
- cmp.w #$0005,d0 ;movec itt1,d0
- beq.s movecitt1d0
- cmp.w #$0006,d0 ;movec dtt0,d0
- beq.s movecdtt0d0
- cmp.w #$0007,d0 ;movec dtt1,d0
- beq.s movecdtt1d0
-
- bra pv_unhandled
-
- ; movec cacr,d0
- moveccacrd0 move.l (sp)+,d0
- move.l #$3111,d0 ;All caches and bursts on
- addq.l #4,2(sp)
- rte
-
- ; movec cacr,d1
- moveccacrd1 move.l (sp)+,d0
- move.l #$3111,d1 ;All caches and bursts on
- addq.l #4,2(sp)
- rte
-
- ; movec vbr,a0
- movecvbra0 move.l (sp)+,d0
- sub.l a0,a0 ;VBR always appears to be at 0
- addq.l #4,2(sp)
- rte
-
- ; movec vbr,a1
- movecvbra1 move.l (sp)+,d0
- sub.l a1,a1 ;VBR always appears to be at 0
- addq.l #4,2(sp)
- rte
-
- ; movec vbr,d1
- movecvbrd1 move.l (sp)+,d0
- moveq.l #0,d1 ;VBR always appears to be at 0
- addq.l #4,2(sp)
- rte
-
- ; movec tc,d0
- movectcd0 addq.l #4,sp
- moveq #0,d0 ;MMU is always off
- addq.l #4,2(sp)
- rte
-
- ; movec tc,d1 +jl+
- movectcd1 move.l (sp)+,d0 ;Restore d0
- moveq #0,d1 ;MMU is always off
- addq.l #4,2(sp)
- rte
-
- ; movec sfc,d1 +jl+
- movecsfcd1 move.l (sp)+,d0 ;Restore d0
- moveq #0,d1
- addq.l #4,2(sp)
- rte
-
- ; movec dfc,d1 +jl+
- movecdfcd1 move.l (sp)+,d0 ;Restore d0
- moveq #0,d1
- addq.l #4,2(sp)
- rte
-
- movecurpd0 ; movec urp,d0 +jl+
- movecsrpd0 ; movec srp,d0
- movecitt0d0 ; movec itt0,d0
- movecitt1d0 ; movec itt1,d0
- movecdtt0d0 ; movec dtt0,d0
- movecdtt1d0 ; movec dtt1,d0
- addq.l #4,sp
- moveq.l #0,d0 ;MMU is always off
- addq.l #4,2(sp) ;skip instruction
- rte
-
- ; movec x,cr
- movectocr move.w ([6,sp],2),d0 ;Get next instruction word
-
- cmp.w #$0801,d0 ;movec d0,vbr?
- beq.s movectovbr
- cmp.w #$1801,d0 ;movec d1,vbr?
- beq.s movectovbr
- cmp.w #$0002,d0 ;movec d0,cacr?
- beq.s movectocacr
- cmp.w #$1002,d0 ;movec d1,cacr?
- beq.s movectocacr
- cmp.w #$1000,d0 ;movec d1,sfc?
- beq.s movectoxfc
- cmp.w #$1001,d0 ;movec d1,dfc?
- beq.s movectoxfc
-
- bra pv_unhandled
-
- ; movec x,vbr
- movectovbr move.l (sp)+,d0 ;Ignore moves to VBR
- addq.l #4,2(sp)
- rte
-
- ; movec dx,cacr
- movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches
- move.l _SysBase,a6
- JSRLIB CacheClearU
- movem.l (sp)+,d1/a0-a1/a6
- move.l (sp)+,d0
- addq.l #4,2(sp)
- rte
-
- ; movec x,sfc
- ; movec x,dfc
- movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC
- addq.l #4,2(sp)
- rte
-
- ; cpusha
- cpushadc
- cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches
- move.l _SysBase,a6
- JSRLIB CacheClearU
- movem.l (sp)+,d1/a0-a1/a6
- move.l (sp)+,d0
- addq.l #2,2(sp)
- rte
-
- ; move usp,a1 +jl+
- moveuspa1 move.l (sp)+,d0
- move usp,a1
- addq.l #2,2(sp)
- rte
-
- ; move usp,a0 +jl+
- moveuspa0 move.l (sp)+,d0
- move usp,a0
- addq.l #2,2(sp)
- rte
-
- ; move a1,usp +jl+
- moved1usp move.l (sp)+,d0
- move a1,usp
- addq.l #2,2(sp)
- rte
-
- ;
- ; Trigger NMI (Pop up debugger)
- ;
-
- _AsmTriggerNMI move.l d0,-(sp) ;Save d0
- move.w #$007c,-(sp) ;Yes, fake NMI stack frame
- pea 1$
- move.w _EmulatedSR,d0
- and.w #$f8ff,d0 ;Set interrupt level in SR
- move.w d0,-(sp)
- move.w d0,_EmulatedSR
-
- move.l $7c.w,-(sp) ;Jump to MacOS NMI handler
- rts
-
- 1$ move.l (sp)+,d0 ;Restore d0
- rts
-
-
- END
-